package se.curalia.slimcache;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;

/**
 * a WMS-call.
 */
public class WMSRequest {


    // OGC WMS request parameter names
    public static final String REQUEST_PARAM = "request";
	public static final String VERSION_PARAM = "version";
	public static final String TILED_PARAM = "tiled";
	public static final String SRS_PARAM = "srs";
	public static final String LAYER_PARAM = "layers";
	public static final String STYLES_PARAM = "styles";
	public static final String BBOX_PARAM = "bbox";
	public static final String ORIGIN_PARAM = "tilesorigin";
	public static final String HEIGHT_PARAM = "height";
	public static final String WIDTH_PARAM = "width";
	public static final String IMAGE_TYPE_PARAM = "format";
	public static final String ERROR_TYPE_PARAM = "exceptions";
    public static final String TRANSPARENT_PARAM = "transparent";

    protected String request;
    protected String version;
    protected String srs;
    protected String layers;
    protected String styles;
    protected BBOX bbox;
    protected int height;
    protected int width;
    protected String imageType;
    protected String errorType;
    protected boolean tiled;
    protected String origin;



    public WMSRequest(HttpServletRequest req) throws Exception {
        this.request = getWMSParam(req,REQUEST_PARAM);
        this.version = getWMSParam(req, VERSION_PARAM);
        this.srs = getWMSParam(req, SRS_PARAM);
        this.layers = getWMSParam(req, LAYER_PARAM);
        this.styles = getWMSParam(req, STYLES_PARAM);
        this.bbox = new BBOX(getWMSParam(req,BBOX_PARAM));
        this.width = Integer.parseInt(getWMSParam(req, (WIDTH_PARAM)));
        this.height = Integer.parseInt(getWMSParam(req, (HEIGHT_PARAM)));
        this.imageType = getWMSParam(req, IMAGE_TYPE_PARAM);
        this.errorType = getWMSParam(req, ERROR_TYPE_PARAM);
        this.origin = getWMSParam(req, ORIGIN_PARAM);
        this.tiled = Boolean.parseBoolean(getWMSParam(req, TILED_PARAM));
    }

    public static String getWMSParam(HttpServletRequest req, String name) {
        String value = req.getParameter(name);
        if(value == null) {
            value =  req.getParameter(name.toUpperCase());
        }
        return value;
    }
    public double getResolution() {
        return getResolution(this.width, this.height, this.bbox);
    }

    private static double getResolution(int width, int height, BBOX bbox) {
        double resX = bbox.getDeltaX() / width;
        double resY = bbox.getDeltaY() / height;
        return Math.max(resX, resY);
    }

    public String getRequest() {
        return request;
    }

    public String getVersion() {
        return version;
    }

    public String getSrs() {
        return srs;
    }

    public String getLayers() {
        return layers;
    }

    public String getStyles() {
        return styles;
    }

    public BBOX getBbox() {
        return bbox;
    }

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    public String getImageType() {
        return imageType;
    }

    public String getErrorType() {
        return errorType;
    }

    public boolean isTiled() {
        return tiled;
    }

    public String getOrigin() {
        return origin;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(REQUEST_PARAM).append(": ").append(this.request).append("\n");
        sb.append(VERSION_PARAM).append(": ").append(this.version).append("\n");

        sb.append(SRS_PARAM).append(": ").append(this.srs).append("\n");
        sb.append(LAYER_PARAM).append(": ").append(this.layers).append("\n");
        sb.append(STYLES_PARAM).append(": ").append(this.styles).append("\n");
        sb.append(BBOX_PARAM).append(": ").append(this.bbox).append("\n");

        sb.append(HEIGHT_PARAM).append(": ").append(this.height).append("\n");
        sb.append(WIDTH_PARAM).append(": ").append(this.height).append("\n");

        sb.append(IMAGE_TYPE_PARAM).append(": ").append(this.imageType).append("\n");
        sb.append(ERROR_TYPE_PARAM).append(": ").append(this.errorType).append("\n");

        sb.append(TILED_PARAM).append(": ").append(this.request).append("\n");
        sb.append(ORIGIN_PARAM).append(": ").append(this.origin).append("\n");
        
        return sb.toString();
    }

    public String toQueryString() throws Exception {
        StringBuffer sb = new StringBuffer();
        addParam(sb, BBOX_PARAM, this.bbox.toString(), true);
        addParam(sb, HEIGHT_PARAM, Integer.toString(this.height) , false);
        addParam(sb, WIDTH_PARAM, Integer.toString(this.width) , false);        
        addParam(sb, IMAGE_TYPE_PARAM, this.imageType, false);

        //sb.append(IMAGE_TYPE_PARAM).append("=").append(this.imageType).append("&");
        //sb.append(ERROR_TYPE_PARAM).append("=").append(this.errorType).append("'&");

        //sb.append(TILED_PARAM).append("=").append(this.request).append("&");
        //sb.append(ORIGIN_PARAM).append("=").append(this.origin);

        return sb.toString();
    }

    private void addParam(StringBuffer sb, String name, String value, boolean first) throws Exception {
        if(!first) {
            sb.append("&");
        }
        sb.append(name).append("=").append(URLEncoder.encode(value,"UTF-8"));
    }


}
